/**
 * @file myfind.c
 * Betriebssysteme Myfind File.
 * 
 * Beispiel 1
 *
 * @author Markus Scharitzer 1410258040 <markus.scharitzer@technikum-wien.at>
 * @author Helene Wiesinger 1410258004 <helene.wiesinger@technikum-wien.at>
 * @author Siegfried Becher 141025035 <siegfried.becher@technikum-wien.at>
 * @date 2015/03/12
 *
 * @version 1.0 
 *
 * Main MyFind Class
 *
 */
/*
 * -------------------------------------------------------------- includes --
 */

#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
#include <malloc.h>
#include <libgen.h>
#include <stdlib.h>
#include "print.h"
#include "owner.h"
#include "parser.h"
#include "type.h"
/*
 * --------------------------------------------------------------- defines --
 */

/*
 * -------------------------------------------------------------- typedefs --
 */

/*
 * --------------------------------------------------------------- globals --
 */

#define MAX_PATH 1024
#define bool int
#define true 1
#define false 0

/*
 * ------------------------------------------------------------- functions --
 */

void doDir(char * path, const char * const * parms);
void doFile(char * file, const char * const * parms);
void check_stuff(char * name, const char * const * parms);
void verify_params(int argc ,const char * const * parms);
int main(int argc, char* argv[]){
  char *path=NULL;
  /** fixed  warning: initialization from incompatible pointer type */
  const char * const * parms = (const char** )argv;
  
  
  if(argc<2)
    {
      print_info(parms);
      return 1;
    }
  verify_params(argc,parms);
  /*pfad muss immer in 1 stehen*/
  path = argv[1];

  /* check file or dir */
  doFile(path,parms);

  return 0;

}

void doDir(char * dirName,const char * const * parms){
  DIR* dp;
  struct stat stbuf;
  struct dirent* dirp; 
  
  if(lstat(dirName, &stbuf)==-1){
	 fprintf (stderr, "lstat failed '%s': %s\n",
	       dirName, strerror (errno));  
	
    /* fehlerbehandlung */
    return;
  }
  
  /*öffnen des directories*/
  dp = opendir(dirName);
  if(!dp){
    /* fehlerbehandlung errno */
    fprintf(stderr, "Directory %s konnte nicht geoeffnet werden\n: %s", dirName, strerror(errno));
    return;
  }
  while ((dirp = readdir(dp))) {
    char * d_name = dirp->d_name;
    /* int path_length = 0; */
    char * path = (char *) malloc(sizeof(char)*(strlen(dirName)+strlen(d_name)+2));
   if(!path){
	fprintf(stderr, "malloc failed\n: %s, %s", dirName, strerror(errno));
	return;
	}
	else{
	strcpy(path, dirName);
	strcat(path, "/");
        strcat(path, d_name);
	}
    if(strcmp(d_name, ".") == 0 ||
     strcmp(d_name, "..") == 0)
    {
      
      continue;
    }
        
    doFile(path,parms);
    
  }
  closedir(dp);
  

}
	
void doFile(char * fileName, const char * const * parms){
  /* FILE *fp; */
  /* fprintf(stderr,parms); */
  struct stat stbuf;
  if(lstat(fileName, &stbuf)==-1){	
    /* fehlerbehandlung */
	 fprintf (stderr, "lstat failed '%s': %s\n",
	       fileName, strerror (errno));  

    return;
  }
	
  check_stuff(fileName,parms);

  
  if(S_ISDIR(stbuf.st_mode))
      {
      doDir(fileName,parms);
      }
  
  return;
}


  

void check_stuff(char * name, const char * const * parms) {
  bool param_valid = true;
  int i = 2;
  bool autoprint = true;
  
while ( parms[i]  && param_valid) 
    {
      if ( strcmp("-name",parms[i])==0 ) {
	param_valid = param_valid && check_name(parms,name,parms[++i]);
      }
      else if ( strcmp("-path",parms[i]) == 0 ) {
	param_valid = param_valid && check_path(parms,name,parms[++i]);
      }
      else if ( strcmp("-user",parms[i]) == 0 ) {
	param_valid = param_valid && check_user(parms,name,parms[++i]);
      }
      else if ( strcmp("-type",parms[i]) == 0 ) {
	param_valid = param_valid && check_type(parms,name,parms[++i]);
      }
      else if ( strcmp("-path",parms[i]) == 0 ) {
	param_valid = param_valid && check_path(parms,name,parms[++i]);
      }
      else if ( strcmp("-nouser",parms[i]) == 0 ) {
	param_valid = param_valid && check_nouser(parms,name);
      }
      else if ( strcmp("-ls",parms[i]) == 0 && param_valid ) {
	autoprint = false;
	print_ls(parms,name);
      }
      else if ( strcmp("-print",parms[i])== 0  && param_valid) {
	autoprint = false;
	print(parms,name);
      }
     /* if(autoprint && param_valid){
	print(name);
	autoprint = false;
      }*/
      i++;
    }
	
  if(!param_valid) return;

  if(autoprint){
    print(parms,name);
  }

}

/**
 *
 * \brief verify_params function
 *
 * verifies that each test has the right amount of values
 *
 * \param argc argument count
 * \param parms array of parameter
 *
 * \return void
 *
 */
void verify_params(int argc ,const char * const * parms)
{
  int counter=2;
  if (argc == 2) return;
  argc = argc-1;
  while ( argc>=counter)
    {
      if ( strcmp("-name",parms[counter])==0 ) {
	if( argc==counter )
	  {
	    fprintf(stderr,"%s: -name takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
	else if ((counter++ <= argc) && ('-' == parms[counter][0]) ) 
	  {
	    fprintf(stderr,"%s: -name takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
      }
      else if ( strcmp("-path",parms[counter]) == 0 ) {
	if( argc==counter )
	  {
	    fprintf(stderr,"%s: -path takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
	else if ((counter++ <= argc) && ('-' == parms[counter][0]) ) 
	  {
	    fprintf(stderr,"%s: -path takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
      }
      else if ( strcmp("-user",parms[counter]) == 0 ) {
	if( argc==counter )
	  {
	    fprintf(stderr,"%s: -user takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
	else if ((counter++ <=argc) && ('-' == parms[counter][0]) ) 
	  {
	    fprintf(stderr,"%s: -user takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
      }
      else if ( strcmp("-type",parms[counter]) == 0 ) {
	if( argc==counter )
	  {
	    fprintf(stderr,"%s: -type takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
	else if ( (counter++<=argc) && ('-' == parms[counter][0]) ) 
	  {
	    fprintf(stderr,"%s: -type takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
      }
      else if ( strcmp("-path",parms[counter]) == 0 ) {
	if( argc==counter )
	  {
	    fprintf(stderr,"%s: -path takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
	else if ((counter++<=argc) && ('-' == parms[counter][0]) ) 
	  {
	    fprintf(stderr,"%s: -path takes exactly one parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
      }
      else if ( strcmp("-nouser",parms[counter]) == 0 ) {
	if (argc == counter) return;
	if ( !('-' == parms[counter+1][0]) ) 
	  {
	    fprintf(stderr,"%s: -nouser takes exactly no parameter\n", parms[0]);
	    print_info(parms); 
	    exit(1);
	  }
      }
      else if ( strcmp("-ls",parms[counter]) == 0  ) {
	if (argc == counter) return;
	if ( !('-' == parms[counter+1][0]) ) 
	  {
	    fprintf(stderr,"%s: -ls takes exactly no parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
      }
      else if ( strcmp("-print",parms[counter])== 0) {
	if (argc == counter) return;
	if ( !('-' == parms[counter+1][0]) ) 
	  {
	    fprintf(stderr,"%s: -print takes exactly no parameter\n", parms[0]);
	    print_info(parms);
	    exit(1);
	  }
      }
      else 
	{
	  fprintf(stderr,"%s: Path must precede Tests\n",parms[0]);
	  print_info(parms);
	  exit(1);
	}
      counter++;
    }
}
